package com.gin.kotlin.gf2gamecommunity.routes

import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.AccountBox
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material3.AssistChip
import androidx.compose.material3.AssistChipDefaults
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SuggestionChip
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import androidx.navigation.toRoute
import androidx.paging.compose.collectAsLazyPagingItems
import com.gin.kotlin.enums.ComplaintUserReason
import com.gin.kotlin.enums.QueryType
import com.gin.kotlin.form.ComplaintUserForm
import com.gin.kotlin.form.UserInfoForm
import com.gin.kotlin.gf2gamecommunity.R
import com.gin.kotlin.gf2gamecommunity.app.App
import com.gin.kotlin.gf2gamecommunity.base.composable.ConfirmDialog
import com.gin.kotlin.gf2gamecommunity.base.composable.Loading
import com.gin.kotlin.gf2gamecommunity.base.composable.MyImage
import com.gin.kotlin.gf2gamecommunity.base.composable.TabInfo
import com.gin.kotlin.gf2gamecommunity.base.composable.TabRowPager
import com.gin.kotlin.gf2gamecommunity.base.util.copyText
import com.gin.kotlin.gf2gamecommunity.composable.HtmlText
import com.gin.kotlin.gf2gamecommunity.composable.TopicLazyColumn
import com.gin.kotlin.gf2gamecommunity.navi.GF2Navigator
import com.gin.kotlin.gf2gamecommunity.viewmodel.TopicListViewModel
import com.gin.kotlin.gf2gamecommunity.viewmodel.UserCenterViewModel
import com.gin.kotlin.response.user.UserInfo
import kotlinx.serialization.Serializable


fun NavGraphBuilder.userCenter(navigator: GF2Navigator) =
    composable<UserCenterRoute>(
        // 从屏幕右侧进入，持续500毫秒
        enterTransition = { slideInHorizontally(tween(500)) { it } },
        // 从屏幕右侧退出，持续500毫秒
        exitTransition = { slideOutHorizontally(tween(500)) { it } },
    ) {
        UserCenterComposable(route = it.toRoute(), navigator = navigator)
    }

@Serializable
data class UserCenterRoute(val uid: Int)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun UserCenterComposable(
    route: UserCenterRoute,
    viewModel: UserCenterViewModel = viewModel(),
    navigator: GF2Navigator
) {
    navigator.apply {
        val state = viewModel.userInfo.fetch(route.uid).observeAsState()
        val userInfo = state.value?.data
        // 是否为当前账号的用户中心
        val isCurrent = App.INSTANCE.currentAccount()?.uid == userInfo?.uid
        val context = LocalContext.current

        val sheetState = rememberModalBottomSheetState()
        var showComplaintSheet by remember { mutableStateOf(false) }

        Scaffold(
            topBar = {
                TopAppBar(navigationIcon = {
                    IconButton(onClick = { onPopBackStack() }) {
                        Icon(imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "后退")
                    }
                }, actions = {
                    IconButton(onClick = { showComplaintSheet = true }) {
                        Icon(painterResource(R.drawable.ic_report_problem_24), contentDescription = "举报")
                    }
                    IconButton(onClick = { viewModel.userInfo.fetch(route.uid, true) }) {
                        Icon(imageVector = Icons.Filled.Refresh, contentDescription = "刷新")
                    }
                }, title = {
                    Text("用户中心")
                })
            },
        ) { paddingValues ->
            userInfo?.apply {
                val modifier = Modifier.padding(paddingValues)
                Column(verticalArrangement = Arrangement.spacedBy(2.dp), modifier = modifier
                    .fillMaxHeight()
                    .padding(8.dp)) {
                    // 用户基础信息
                    BaseUserInfo(userInfo, isCurrent = isCurrent, onNavigateToUserRelatedList = { onNavigateToUserRelatedList(it) })
                    // 游戏数据
                    UserGameInfo(userInfo, onNavigateToGameInfo = { onNavigateToGameInfo(it) })
                    // 主题、评论、收藏、资料、隐私
                    ExtraUserInfo(userInfo, isCurrent = isCurrent, onNavigateToCommentList = { onNavigateToCommentList(it) }, onRefresh = {
                        viewModel.userInfo.fetch(route.uid, true)
                    })
                }
            } ?: Loading()

            if (showComplaintSheet) ModalBottomSheet(sheetState = sheetState, onDismissRequest = { showComplaintSheet = false }) {
                Column(modifier = Modifier.padding(16.dp)) {
                    Text("举报用户: ", fontWeight = FontWeight.Bold)
                    LazyVerticalGrid(
                        columns = GridCells.Fixed(2),
                        horizontalArrangement = Arrangement.spacedBy(4.dp),
                        verticalArrangement = Arrangement.spacedBy(4.dp),
                    ) {
                        items(items = ComplaintUserReason.entries.toList()) { reason ->
                            SuggestionChip(onClick = {
                                viewModel.complaint(ComplaintUserForm(route.uid, reason)) {
                                    showComplaintSheet = false
                                }
                            }, label = { Text(reason.des) })
                        }
                    }
                }
            }
        }
    }
}

@Composable
private fun UserInfoCard(title: String, modifier: Modifier = Modifier, content: @Composable () -> Unit) {
    Card(shape = RoundedCornerShape(16.dp), modifier = modifier) {
        Column(modifier = Modifier.padding(8.dp)) {
            Text(title, fontWeight = FontWeight.Bold, fontSize = 22.sp)
            Spacer(modifier = Modifier.height(2.dp))
            HorizontalDivider()
            Spacer(modifier = Modifier.height(2.dp))
            content()
        }
    }
}

@Composable
private fun BaseUserInfo(userInfo: UserInfo, viewModel: UserCenterViewModel = viewModel(), isCurrent: Boolean, onNavigateToUserRelatedList: (route: UserRelatedListRoute) -> Unit) {
    val context = LocalContext.current
    userInfo.apply {
        var followed by remember { mutableStateOf(isFollow) }
        Row {
            Column {
                MyImage(model = avatar, modifier = Modifier
                    .clip(CircleShape)
                    .width(80.dp))
                if (!isCurrent) AssistChip(onClick = {
                    viewModel.follow(uid) {
                        followed = !followed
                        isFollow = followed
                    }
                }, label = { Text(if (followed) "已关注" else "未关注") }, leadingIcon = {
                    Icon(if (followed) Icons.Filled.Check else Icons.Filled.Add, contentDescription = null, Modifier.size(AssistChipDefaults.IconSize))
                })
            }
            Spacer(modifier = Modifier.width(8.dp))
            Column {
                Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
                    AssistChip(onClick = {
                        context.copyText("${App.HOST}/user?id=${uid}", "已复制地址")
                    }, label = { Text("$nickName Lv. $level", fontWeight = FontWeight.Bold) }, leadingIcon = {
                        Icon(painterResource(R.drawable.ic_content_copy_24), contentDescription = "复制用户中心地址", Modifier.size(AssistChipDefaults.IconSize))
                    })
                    SuggestionChip(onClick = { }, label = { Text("获赞: $likes") })
                }
                Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
                    AssistChip(onClick = {
                        onNavigateToUserRelatedList(UserRelatedListRoute(uid, ListType.FANS))
                    }, label = { Text("粉: $fans") }, leadingIcon = {
                        Icon(Icons.Filled.Person, contentDescription = "查询粉丝列表", Modifier.size(AssistChipDefaults.IconSize))
                    })
                    AssistChip(onClick = {
                        onNavigateToUserRelatedList(UserRelatedListRoute(uid, ListType.FOLLOWS))
                    }, label = { Text("关: $follows") }, leadingIcon = {
                        Icon(Icons.Filled.Person, contentDescription = "查询关注列表", Modifier.size(AssistChipDefaults.IconSize))
                    })
                    SuggestionChip(onClick = { }, label = { Text(ipLocation.trim()) })
                }
                signature.takeIf { it.isNotEmpty() }?.also { Text(it, modifier = Modifier.graphicsLayer { alpha = 0.7f }) }
            }
        }
    }
}

/**
 * 游戏数据卡片
 * @param userInfo UserInfo
 * @param modifier Modifier
 * @param onNavigateToGameInfo (route: GameInfoRoute) -> Unit
 */
@Composable
private fun UserGameInfo(userInfo: UserInfo, modifier: Modifier = Modifier, onNavigateToGameInfo: (route: GameInfoRoute) -> Unit) {
    val context = LocalContext.current
    userInfo.apply {
        if (showGame) UserInfoCard("游戏数据") {
            Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
                AssistChip(onClick = {
                    if (App.INSTANCE.currentAccount()?.uid != uid && !userInfo.showGame) {
                        App.toast("该数据未公开")
                    } else {
                        onNavigateToGameInfo(GameInfoRoute(uid))
                    }
                }, label = { Text(gameNickName) }, leadingIcon = {
                    Icon(Icons.Filled.AccountBox, contentDescription = "跳转到游戏数据界面", Modifier.size(AssistChipDefaults.IconSize))
                })
                SuggestionChip(onClick = { }, label = { Text("Lv. $gameCommanderLevel") })
                AssistChip(onClick = {
                    context.copyText(uid.toString(), "已复制UID")
                }, label = { Text(gameUid.toString()) }, leadingIcon = {
                    Icon(painterResource(R.drawable.ic_content_copy_24), contentDescription = "复制uid", Modifier.size(AssistChipDefaults.IconSize))
                })
            }
        }
    }
}

@Composable
private fun ExtraUserInfo(
    userInfo: UserInfo,
    modifier: Modifier = Modifier,
    onNavigateToCommentList: (route: CommentListRoute) -> Unit, onRefresh: () -> Unit, isCurrent: Boolean
) {
    userInfo.apply {
        Column {
            val tabList = mutableListOf(
                TabInfo("帖子", R.drawable.ic_topic_24) { UserTopic(uid, onNavigateToCommentList = onNavigateToCommentList) },
                TabInfo("评论", R.drawable.ic_comment_24) { UserComment(uid, onNavigateToCommentList = onNavigateToCommentList) },
            )
            if (showFavor && favors > 0 || isCurrent) {
                tabList.add(TabInfo("收藏", R.drawable.ic_favorite_24) { UserFavor(uid, onNavigateToCommentList = onNavigateToCommentList) })
            }
            if (isCurrent) {
                tabList.add(TabInfo("资料", R.drawable.ic_edit_note_24) { UserInfoEdit(userInfo, onRefresh = onRefresh) })
                tabList.add(TabInfo("隐私", R.drawable.ic_privacy_tip_24) { UserPrivacy(uid) })
            }
            TabRowPager(tabList, beyondViewportPageCount = 1)
        }

    }
}

/**
 * 用户发布的主题
 * @param userId Int
 * @param viewModel TopicListViewModel
 */
@Composable
private fun UserTopic(userId: Int, viewModel: TopicListViewModel = viewModel(), onNavigateToCommentList: (route: CommentListRoute) -> Unit) {
    val lazyPagingItems = viewModel.topicList.fetch(TopicListRoute(QueryType.USER_TOPIC, userId)).collectAsLazyPagingItems()

    if (lazyPagingItems.itemCount > 0)
        TopicLazyColumn(lazyPagingItems = lazyPagingItems, onNavigateToCommentList = onNavigateToCommentList, showAvatar = false, toppedTopics = null)
    else {
        Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
            Text("暂无数据", fontSize = 24.sp)
        }
    }
}

/**
 * 用户发布的评论
 * @param userId Int
 * @param viewModel UserCenterViewModel
 * @param modifier Modifier
 */
@Composable
private fun UserComment(userId: Int, viewModel: UserCenterViewModel = viewModel(), modifier: Modifier = Modifier, onNavigateToCommentList: (route: CommentListRoute) -> Unit) {
    val lazyPagingItems = viewModel.commentUser.fetch(userId).collectAsLazyPagingItems()

    if (lazyPagingItems.itemCount > 0) LazyColumn(modifier = modifier, verticalArrangement = Arrangement.spacedBy(2.dp)) {
        items(lazyPagingItems.itemCount) { index ->
            lazyPagingItems[index]?.apply {
                Card(border = BorderStroke(2.dp, CardDefaults.cardColors().disabledContentColor), modifier = Modifier.clickable {
                    onNavigateToCommentList(CommentListRoute(topicId = topicId, temporaryTitle = title))
                }) {
                    Column(modifier = Modifier.padding(4.dp)) {
                        // 正文
                        HtmlText(item = this@apply, html = content)
                        // 发布时间
                        Text(createTime, modifier = Modifier.graphicsLayer { alpha = 0.7f })
                        // 标题
                        Text("回复帖子: $title", modifier = Modifier.graphicsLayer { alpha = 0.7f })
                    }
                }

            }
        }
    } else {
        Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
            Text("暂无数据", fontSize = 24.sp)
        }
    }
}

/**
 * 用户的收藏
 * @param userId Int
 * @param viewModel TopicListViewModel
 * @param modifier Modifier
 */
@Composable
private fun UserFavor(userId: Int, viewModel: TopicListViewModel = viewModel(), modifier: Modifier = Modifier, onNavigateToCommentList: (route: CommentListRoute) -> Unit) {
    val lazyPagingItems = viewModel.topicList.fetch(TopicListRoute(QueryType.USER_FAVOR, userId)).collectAsLazyPagingItems()
    TopicLazyColumn(lazyPagingItems = lazyPagingItems, onNavigateToCommentList = onNavigateToCommentList, toppedTopics = null)
}

/**
 * 资料编辑
 * @param userInfo UserInfo
 * @param viewModel UserCenterViewModel
 * @param modifier Modifier
 */
@Composable
private fun UserInfoEdit(userInfo: UserInfo, viewModel: UserCenterViewModel = viewModel(), modifier: Modifier = Modifier, onRefresh: () -> Unit) {
    var nickname by remember { mutableStateOf(userInfo.nickName) }
    var signature by remember { mutableStateOf(userInfo.signature) }
    var avatar by remember { mutableStateOf(userInfo.avatar) }

    var showAvatarDialog by remember { mutableStateOf(false) }

    Column(horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(8.dp),
        modifier = Modifier
            .fillMaxWidth()
            .padding(8.dp)) {
        MyImage(avatar, modifier = Modifier
            .clip(CircleShape)
            .size(120.dp)
            .clickable {
                showAvatarDialog = true
            })
        TextField(
            value = nickname,
            onValueChange = { nickname = it },
            label = { Text("昵称(30天冷却)") }
        )
        TextField(
            value = signature,
            onValueChange = { signature = it },
            label = { Text("签名(20字以内)") }
        )
        Button(onClick = {
            viewModel.modify(UserInfoForm(
                avatar = avatar,
                signature = signature,
                nickName = nickname
            )) {
                onRefresh()
            }
        }) { Text("保存") }
    }

    when {
        showAvatarDialog -> {
            var selectedAvatar by remember { mutableStateOf(userInfo.avatar) }
            ConfirmDialog(onDismissRequest = { showAvatarDialog = false }, onConfirmation = {
                showAvatarDialog = false
                avatar = selectedAvatar
            }) {
                Column {
                    val state = viewModel.avatarList.liveData.observeAsState()
                    viewModel.avatarList.fetch()
                    MyImage(selectedAvatar, modifier = Modifier
                        .clip(CircleShape)
                        .size(80.dp))
                    LazyVerticalGrid(GridCells.Adaptive(minSize = 64.dp), modifier = Modifier.height(300.dp)) {
                        state.value?.also { list ->
                            itemsIndexed(items = list) { _, item ->
                                MyImage(item.imgAddr, modifier = Modifier
                                    .clip(CircleShape)
                                    .size(60.dp)
                                    .clickable { selectedAvatar = item.imgAddr })
                            }
                        }
                    }
                }
            }
        }
    }
}

/**
 * 隐私设置
 * @param userId Int
 * @param viewModel UserCenterViewModel
 * @param modifier Modifier
 */
@Composable
private fun UserPrivacy(userId: Int, viewModel: UserCenterViewModel = viewModel(), modifier: Modifier = Modifier) {
    val state = viewModel.privacy.fetch(userId).observeAsState()

    state.value?.data?.also { items ->
        LazyColumn(modifier = modifier, verticalArrangement = Arrangement.spacedBy(2.dp)) {
            items(items = items) { config ->
                Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
                    Text(config.name)
                    Switch(checked = config.show, onCheckedChange = { viewModel.setPrivacy(userId, config.type) })
                }
            }
        }

    } ?: Loading()
}
